-module(couchdb).
-define(COUCHURL,"http://127.0.0.1:5984/").
-define(COUCHDB,"http://127.0.0.1:5984/cust_db/").
-export([query_and_insert_cust_asyn/2,add/2,modify/2,rev/2,post/2,get/1]).

rev(DB,ID) ->
    URI = lists:flatten([?COUCHURL,DB,"/_design/common/_view/rev?key=\"",ID,"\""]),
    case httpc:request(URI) of
    {ok,{{_,404,_},_,_}} ->
        {error,not_found};
    {ok,{{_,200,_},_,Body}} ->
        case rfc4627:decode(Body) of
        {ok,{obj,Res},_} ->
            {"rows",[{obj,Rev_Rec}|_]} = lists:keyfind("rows",1,Res),
            {"value",Rev} = lists:keyfind("value",1,Rev_Rec),
            {ok,Rev};
        _ ->
            {error, malformat}
        end;
    Res ->
        {error,unspecific}
    end.

post(DB, {obj,Fields}) ->
    Data = rfc4627:encode({obj,Fields}),
    URI = lists:flatten([?COUCHURL,DB]),
    case httpc:request(post,
            {URI,[{"Content-Length",length(Data)}],"application/json",Data},
            [],[],default) of
    {ok,{{_,201,_},_,Body}} ->
        {ok,{obj,Res},_} = rfc4627:decode(Body),
        {_,Id} = lists:keyfind("id",1,Res),
        {ok,binary_to_list(Id)}; %%keep the interface solidate
    {ok,{{_,409,_},_,_}} ->
        {error,"duplicate"};
    Res ->
        io:format("~p ~p\n",[Res,URI]),
        {error,"unspecified"}
    end.
    
%% it is update, rev required to update
put(DB,ID,{obj,Fields}) ->
    {ok,Rev} = rev(DB,ID),
    Data = rfc4627:encode({obj,[{"_rev",Rev} | Fields]}),
    URI = lists:flatten([?COUCHURL,DB,"/",ID]),
        case httpc:request(put,
            {URI,[{"Content-Length",length(Data)}],"application/json",Data},
            [],[],default) of
        {ok,{{_,201,_},_,Body}} ->
            {ok,{obj,Res},_} = rfc4627:decode(Body),
            {"rev",New_Rev} = lists:keyfind("rev",1,Res),
            {ok,New_Rev};
        Res ->
            {error,unspecific}
    end.
    
change(DB,{obj,Fields}) ->
    post(DB,{obj,[{"_rev","1-2902191555"}|Fields]}).
    
get(DB,doc,ID) ->
    URI = lists:flatten([?COUCHURL,DB,"/",ID]),
    case httpc:request(URI) of
    {ok,{{_,404,_},_,_}} ->
        {error,not_found};
    {ok,{{_,200,_},_,Body}} ->
        case rfc4627:decode(Body) of
        {ok,Res,_} ->
            {ok,Res};
        _ ->
            {error, malformat}
        end;
    Res ->
        {error,unspecific}
    end.
get(DB) ->
    URI = lists:flatten([?COUCHURL,DB,"/","_all_docs"]),
        case httpc:request(URI) of
    {ok,{{_,404,_},_,_}} ->
        {error,not_found};
    {ok,{{_,200,_},_,Body}} ->
        case rfc4627:decode(Body) of
        {ok,{obj,Res},_} ->
            {ok,lists:keyfind("rows",1,Res)};
        _ ->
            {error, malformat}
        end;
    Res ->
        {error,unspecific}
    end.
get(DB,queue,View,QueryInfo) ->
    {ok}.

get() ->
	{ok,{Status,_,Body}} = httpc:request("http://127.0.0.1:5984/cust_db/_design/cust_db/_view/brief"),
	rfc4627:decode(Body).
    
%% use the mobile number as document id
query_and_insert_cust_asyn(Mobile,Name) ->  
    case get("cust_db",doc,Mobile) of
    {ok,Cust} ->
        {ok,Mobile};
    {error,not_found} ->
        add(Mobile,Name);
    _ ->
        {error,unspecific}
    end.
    
%%    case httpc:request(Url) of
%%    {ok,{{_,404,_},_,_}} ->
%%        %% no custom found
%%        add(Mobile,Name);
%%    {ok,{{_,200,_},_,_}} ->
%%        {ok,Mobile};
%%    Res ->
%%        io:format("~p ~p\n",[Res,Url]),
%%        {error,unspecific}
%%    end.

add(Mobile,Name) ->
    Cust = {
        obj,[{"_id",list_to_binary(Mobile)},
            {"Name",list_to_binary(Name)},
            {"Mobile",list_to_binary(Mobile)}
            ]},
    post("cust_db",Cust).
modify(Mobile,Name) ->
    Cust = {
            obj,[{"Name",list_to_binary(Name)},
            {"Mobile",list_to_binary(Mobile)}
            ]},
    put("cust_db",Mobile,Cust).
    
%%    Data = rfc4627:encode(Cust),
%%    Request = {"http://127.0.0.1:5984/cust_db",[{"Content-Length",length(Data)}],"application/json",Data},
%%	case httpc:request(post,Request,[],[],default) of 
%%    {ok,{{_,201,_},_,Body}} ->
%%        {ok,{obj,Fields},_} = rfc4627:decode(Body),
%%        {_,CustId} = lists:keyfind("id",1,Fields),
%%        {ok,CustId};
%%    {ok,{{_,409,_},_,_}} ->
%%        {error,"duplicate"};
%%    Res ->
%%        io:format("~p\n",[Res]),
%%        {error,"unspecified"}
%%    end.
